dbt CloudのCIジョブで差分があるmodelだけを実行&テストしてみた #dbt
さがらです。
dbt CloudのCIジョブで差分があるmodelだけを実行&テストする方法を試してみたので、その内容をまとめてみます。
dbt CloudにおけるCIについて
まず前提として、dbt CloudではCI(継続的インテグレーション)を簡単に設定可能です。詳細は下記ブログをご覧ください。
dbt CloudでのCIの基本的な実装は上記のブログの通りなのですが、CIを担うジョブで実行するコマンドにdbt run
やdbt test
を指定すると、特にコードを変えていないmodelまで実行されてしまい、不要にストレージやコンピュートリソースを使ってしまいます。
この対策として、dbtには差分が発生したmodelだけを実行対象とする機能がありますので、その機能について次章以降で書いていきます。
差分だけを実行するCIジョブの設定方法
事前準備:本番デプロイ用のジョブの設定
差分だけを実行するCIジョブを設定するには、本番デプロイ用のジョブを設定し、一度でも実行しておく必要があります。
後で設定するCIジョブは、この本番デプロイ用のジョブにより生成されるArtifactsとの差分を確認する必要があるからです。
下図は私が設定したジョブの内容です。
CIジョブの設定
続いて、CI用のジョブを設定していきます。
CIジョブを設定する時のポイントは3点あります。
DEFER TO PREVIOUS RUN STATE?の設定
まず1つ目、dbt Cloudのジョブの設定にDEFER TO PREVIOUS RUN STATE?
という項目があります。
この設定項目で指定したジョブのArtifactと、CIジョブにより生成されるArtifact、この2つの差分を確認できるようになります。 先程、本番デプロイ用のジョブを先に設定して実行したのは、この差分を検知するためです。
設定出来るジョブはドロップダウンのリストで表示されるので、本番デプロイ用のジョブを指定します。
実行するコマンド
次に2つ目、実行するコマンドなのですが、--select state:modified+
とオプションを指定する必要があります。
このオプションはどういう意味かというと、
state:modified
により、先程DEFER TO PREVIOUS RUN STATE?
で設定したジョブと差分があるmodelだけを実行対象とする- 末尾に
+
をつけることで、差分があったmodelより下流に位置するmodelも全て実行する
ということが可能になります。
dbt ver1.0.0からbuild
が使えるようになったので、dbt build --select state:modified+
とCIジョブを指定しておきます。
Pull Requestsが発行されたときに実行するように設定
最後に3つ目、このCIジョブはPull Requestが発行された時のみ実行するようにしたいです。
Pull Request発行➟CIジョブが回る➟問題ないことを確認しPull Request承認➟本番用のブランチにマージ、という一連のプロセスを行うためです。
設定方法としては、TriggersのRUN ON PULL REQUESTS?
にチェックを入れればOKです。
この3つの設定が出来たら、Save
を押してジョブを保存します。参考までに、設定したCIジョブの設定全体の画像をポイント3点赤枠で囲んだ上で載せておきます。
実際の挙動
先程設定したCIジョブが上手く動くのか、確認していきます!
対象のmodel
まず、検証に使うのはdbtチュートリアルでも使用するjaffle_shopです。(DWHはSnowflakeで若干カラム構成を変えていますが)
リネージは下図のようになっています。
この時、stg_customers.sql
にだけ、下図のようにlast_name
に対してtrimする処理を入れてみます。
これにより本番環境で動いているジョブとの差分が、生まれました。この上でCIジョブを回してみます。
一度コミットした上で、dbt CloudからPull Requestを開きます。
Pull requestを作ります。
少し時間が経つと、dbt Cloudを介してCIジョブが走ります。
CIジョブが無事に終わると、下図のように表示されます。
ちなみに、接続先のSnowflakeではCIジョブ用のスキーマが作られるのですが、今回変更を行ったstg_customers.sql
とその下流に位置するcustomers.sql
だけが実行されていることがわかると思います。
ここで「あれ、customers.sql
はstg_orders.sql
も参照しているはずだけど、大丈夫なの?」と思った方いると思います。私も思いましたw
なんと、変更を加えていないmodelを参照する場合は、DEFER TO PREVIOUS RUN STATE?
で指定したジョブ(つまり本番デプロイ用ジョブ)で作成されたテーブルを使用しているのです。上手いこと出来ていますね~。
最後に
DEFER TO PREVIOUS RUN STATE?
などの機能を用いて、CIジョブでは変更を加えたmodelだけを実行対象とする方法についてまとめてみました。
この機能を使えば、CIジョブにおけるDWHのストレージとコンピュートリソースの使用を抑えることが出来ますね!
私個人としては「dbt Cloudユーザーはみんな入れるべきでは?」と感じた機能なので、ぜひこの機能を活用していきましょう!